package org.tjc.net.manager.config.json;

import lombok.Data;
import org.tjc.net.manager.exception.ParseConfException;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: tjc
 * @description
 * @Date Created in 18:11 2020-12-12
 */
@Data
public class NgServerModule extends NgModule {

    private int port;
    private String serverName;


    private List<NgLocationModule> locations = new ArrayList<>();

    public static ModuleSet ngSet = (ctx, conf) -> {
        List<Object> serverConfs = conf.getList("");
        List<Configuration> serverConfList = serverConfs.stream().map(Configuration::from).collect(Collectors.toList());


        for (Configuration serverConf : serverConfList) {
            NgServerModule serverModule = new NgServerModule();

            serverModule.setCtx(ctx);

            for (String key : serverConf.getKeys()) {
                if (!MetaNgCommand.contains(key)) {
                    throw new ParseConfException("unexpect key: " + key);
                }

                MetaNgCommand subCmd = MetaNgCommand.get(key);
                if (subCmd.getType() == MetaNgCommand.CMD_MODULE) {
                    Configuration subConf = serverConf.getConfiguration(key);
                    subCmd.invoke(serverModule, subConf);
                } else if (subCmd.getType() == MetaNgCommand.CMD_LINE) {
                    Object value = serverConf.get(key);
                    subCmd.invoke(serverModule, key, value);
                }
            }
            ((NgHttpModule) ctx).addServer(serverModule);
        }
    };

    public void addLocation(NgLocationModule location) {
        this.locations.add(location);
    }


    @Override
    public void init() {
        Map<String, NgCommand> cmdMap = getCommands().stream().collect(Collectors.toMap(NgCommand::getName, ngCommand -> ngCommand));

        NgCommand cmd = null;

        if ((cmd = cmdMap.get("port")) != null) {
            this.port = (int) cmd.getValues().get(0);
        } else {
            this.port = 80;
        }

        if((cmd = cmdMap.get("server_name")) != null) {
            this.serverName = (String) cmd.getValues().get(0);
        } else {
            this.serverName = "127.0.0.1";
        }

        locations.stream().forEach(NgLocationModule::init);
    }
}
